import { getLocalStorage } from '@/utils/commonUtils'

// 封装webSocket
class Socket {
  private socket: WebSocket // 连接实例
  private readonly url: string = '' // 地址
  private heartbeatInterval: NodeJS.Timeout | null // 心跳定时器
  private reconnectTimer: NodeJS.Timeout | null // 重连定时器
  private onmessage: (data: MessageEvent<any>) => void // ws信息回调

  // 构造函数
  constructor(url: string, onmessage: (data: MessageEvent<any>) => void) {
    this.url = url
    this.heartbeatInterval = null
    this.reconnectTimer = null
    this.onmessage = onmessage

    // 判断是否支持webSocket
    if (typeof window.WebSocket !== 'undefined') {
      this.socket = new WebSocket(this.url)
      this.bindingEvents()
      this.heartbeat()
    } else {
      throw new Error('WebSocket is not supported by your browser.')
    }
  }

  // 绑定事件
  bindingEvents() {
    // 连接完成
    this.socket.onopen = (event) => {
      console.log('WebSocket 已连接', event)
      this.connectionOpen()
    }

    // 连接关闭时
    this.socket.onclose = (event) => {
      console.log('连接被关闭', event)
      this.reconnect()
    }

    // ws消息
    this.socket.onmessage = (event) => {
      this.message(event)
    }

    this.socket.onerror = (event) => {
      console.log('连接错误', event)
      console.log(JSON.parse(JSON.stringify(event)))
    }
  }

  // 连接成功
  connectionOpen() {
    this.send(JSON.stringify({ type: 1 }))
  }

  // ws消息
  message(event: MessageEvent<any>) {
    this.onmessage(event)
  }

  // 发送ws消息
  send(data: string | ArrayBufferLike | Blob | ArrayBufferView) {
    this.socket.send(JSON.stringify(data))
  }

  // 重连接
  reconnect() {
    if (getLocalStorage('clientId')) {
      console.log('开始重连')
      this.reconnectTimer = setTimeout(() => {
        this.connectionClose()
        this.socket = new WebSocket(this.url)
        this.bindingEvents()
        this.heartbeat()
      }, 5000)
    }
  }

  // 连接关闭时
  connectionClose() {
    this.reconnectTimer && clearTimeout(this.reconnectTimer)
    this.heartbeatInterval && clearInterval(this.heartbeatInterval)
    this.socket.close()
  }

  // 心跳
  heartbeat() {
    this.heartbeatInterval && clearInterval(this.heartbeatInterval)
    this.heartbeatInterval = setInterval(() => {
      if (this.socket.readyState !== 1) {
        return
      }
      this.send(JSON.stringify({ type: 1 }))
    }, 30000)
  }
}

export default Socket

// 使用
// import Socket from '@/utils/socket'
// import { getLocalStorage, getUrl } from '@/utils/commonUtils'

// const ws = new Socket(getUrl('ws', '/asset', { clientId: getLocalStorage('clientId'), userId: useStore?.userInfo.id! }), (data) => {
//   console.log(data, 'ws数据来了')
//   if (data) {
//     const res = JSON.parse(data.data)
//     console.log(res)
//   }
// })
